using System;
using System.Collections.Generic;
using UnityEngine;

namespace AutoChess
{ class ActorCmpt
    {
        private class RegisterAttrChangeData
        {
            public int m_attrId;
            public Delegate m_handler;

            public RegisterAttrChangeData(int attrId, Delegate handler)
            {
                m_attrId = attrId;
                m_handler = handler;
            }
        }

        private bool m_callStart = false;
        private bool m_calledOnDestroy = false;
        protected GameActor m_actor;
        
        private List<RegisterAttrChangeData> m_registerAttrChanged = new List<RegisterAttrChangeData>();

        public GameActor OwnActor
        {
            get
            {
                if (m_actor != null && m_actor.IsDestroyed)
                {
                    m_actor = null;
                    return null;
                }

                return m_actor;
            }
        }

        public Transform transform
        {
            get
            {
                var ownActor = OwnActor;
                if (ownActor != null)
                {
                    return ownActor.ActorTrans.GoTrans;
                }

                return null;
            }
        }

        #region 操作

        public bool BeforeAddToActor(GameActor actor)
        {
            m_actor = actor;
            m_callStart = false;

            Awake();
            return true;
        }

        public void BeforeDestroy()
        {
            if (m_calledOnDestroy)
            {
                return;
            }

            m_calledOnDestroy = true;
            if (m_actor != null)
            {
                ClearAllEventChangeHanlder();
                OnDesstroy();
            }
        }

        public void CallUpdate()
        {
            if (!m_callStart)
            {
                m_callStart = true;
                Start();
            }
            Update();
        }

        public void CallLateUpdate()
        {
            //下一帧继续
            if (!m_callStart)
            {
                return;
            }
            LateUpdate();
        }

        public void CallOnEnterMap()
        {
            OnEnterMap();
        }

        #endregion

        #region 拓展接口

        protected virtual void Awake()
        {
        }

        protected virtual void Start()
        {
        }

        protected virtual void LateUpdate()
        {
        }

        protected virtual void Update()
        {
            
        }

        protected virtual void OnDesstroy()
        {
        }

        protected virtual void OnEnterMap()
        {
        }

        #endregion

        #region DEBUG
        
        
        #endregion
        
        #region Event操作函数

        public void AddEventListener(ActorEventType evnetType, Action eventCallback)
        {
            m_actor.Event.AddEventListener(evnetType,eventCallback,this);
        }
        
        public void AddEventListener<T>(ActorEventType evnetType, Action<T> eventCallback)
        {
            m_actor.Event.AddEventListener<T>(evnetType,eventCallback,this);
        }

        public void AddEventListener<T,U>(ActorEventType evnetType, Action<T,U> eventCallback)
        {
            m_actor.Event.AddEventListener<T,U>(evnetType,eventCallback,this);
        }
        
        public void AddEventListener<T,U,V>(ActorEventType evnetType, Action<T,U,V> eventCallback)
        {
            m_actor.Event.AddEventListener<T,U,V>(evnetType,eventCallback,this);
        }


        public void RegAttrChangeEvent<T>(ActorActionAttrDef attrId, Action<T, T> handler)
        {
            m_registerAttrChanged.Add(new RegisterAttrChangeData((int)attrId,handler));
            OwnActor.Atrr.RegAttrChangeEvent((int)attrId,handler);
        }

        private void ClearAllEventChangeHanlder()
        {
            var attr = OwnActor.Attr;
            for (int i = 0; i < m_registerAttrChanged.Count; i++)
            {
                var data = m_registerAttrChanged[i];
                attr.UnRegAttrChangeEvent(data.m_attrId, data.m_handler);
            }
        }

        #endregion
    }
}